<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    /* 
        Promise
        Promise 是异步编程的一种解决方案，比传统的解决方案——回调函数和事件——更合理和更强大。

        所谓Promise，简单说就是一个容器，里面保存着某个未来才会结束的事件（通常是一个异步操作）的结果。从语法上说，Promise 是一个对象，从它可以获取异步操作的消息。Promise 提供统一的 API，各种异步操作都可以用同样的方法进行处理。

        如何创建Promise?  => 通过构造函数创建
        var p = new Promise();  // 报错 => 构造函数Promise要求接收一个回调函数
        console.log(p);

        Promise实例的状态有哪些?
        pending(进行中)
        fulfilled(已成功) / resolved
        rejected(以失败)

        如何改变Promise实例的状态?
        resolve()   将Promise实例的状态由pending(进行中) 改为 fulfilled(已成功)
        reject()    将Promise实例的状态由pending(进行中) 改为 rejected(以失败)

        resolve(arg)/reject(arg)  除了改变Promise实例的状态,还可以接收一个参数,将该参数作为数据存储到Promise实例中 

        resolve函数的作用是，将Promise对象的状态从“未完成”变为“成功”（即从 pending 变为 resolved），在异步操作成功时调用，并将异步操作的结果，作为参数传递出去；reject函数的作用是，将Promise对象的状态从“未完成”变为“失败”（即从 pending 变为 rejected），在异步操作失败时调用，并将异步操作报出的错误，作为参数传递出去。

        Promise的特征:
        （1）对象的状态不受外界影响。Promise对象代表一个异步操作，有三种状态：pending（进行中）、fulfilled（已成功）和rejected（已失败）。只有异步操作的结果，可以决定当前是哪一种状态，任何其他操作都无法改变这个状态 (用户需要根据异步操作的结果,决定调用resolve()/reject()来改变状态)

        （2）一旦状态改变，就不会再变，任何时候都可以得到这个结果。Promise对象的状态改变，只有两种可能：从pending变为fulfilled和从pending变为rejected。只要这两种情况发生，状态就凝固了，不会再变了，会一直保持这个结果，这时就称为 resolved（已定型）
    
    
    
    
    */


    // 实例化 => 通过构造函数创建对象的方式,叫做实例化,被创建的对象称之为实例化对象
    // p => 构造函数Promise的实例化对象 (Promise实例 Promise对象)
    /*
    var p = new Promise(function (resolve, reject) {
        // (1) 构造函数Promise要求接收一个回调函数(所谓的容器),常用于接收异步操作(同步也可以)
        // (2) 接收的回调函数(容器)属于同步任务,在new Promise() 创建实例化对象过程中立即执行
        // (3) 回调函数的两个参数分别是resolve和reject(形参)。它们是两个函数，由 JavaScript 引擎提供，不用自己部署 (用于改变Promise实例的状态)

        console.log("Promise结束的回调函数执行了");



    });
    console.log(p); 
    
    */
    /*
        p = {
            [[PromiseState]]:"pending",   // Promise实例的状态
            [[PromiseResult]]: undefined  // Promise实例中存储的数据
        }

    
    */

    // 此代码中没有包含异步代码  => 全都在new Promise()创建实例化对象过程中执行  (创建Promise实例,立即改变了它的状态,并存储数据)
    /* var p = new Promise(function (resolve, reject) {
        // (1) 构造函数Promise要求接收一个回调函数(所谓的容器),常用于接收异步操作(同步也可以)
        // (2) 接收的回调函数(容器)属于同步任务,在new Promise() 创建实例化对象过程中立即执行
        // (3) 回调函数的两个参数分别是resolve和reject(形参)。它们是两个函数，由 JavaScript 引擎提供，不用自己部署 (用于改变Promise实例的状态)

        console.log("Promise结束的回调函数执行了");

        // resolve();
        // reject();

        // resolve(true);
        reject(false);



    });
    console.log(p); */


    // Promise根据异步操作结果改编状态
    var p = new Promise(function (resolve, reject) {
        // (1) 构造函数Promise要求接收一个回调函数(所谓的容器),常用于接收异步操作(同步也可以)
        // (2) 接收的回调函数(容器)属于同步任务,在new Promise() 创建实例化对象过程中立即执行
        // (3) 回调函数的两个参数分别是resolve和reject(形参)。它们是两个函数，由 JavaScript 引擎提供，不用自己部署 (用于改变Promise实例的状态)

        console.log("Promise接收的的回调函数执行了");

        // 投硬币
        setTimeout(() => {
            var num = Math.random();   // 0-1 

            // 根据异步操作的结果, 自行决定如何改变状态 => 演示
            // if (num > 0.5) { // 正面(不拖堂)
            //     resolve("老王不拖堂");  // {<fulfilled>:"老王不拖堂"}
            // } else {  // 反面
            //     reject("老王拖堂了"); // {<rejected>: "老王拖堂了"}
            // }

            resolve("老王不拖堂");
            reject("老王拖堂了");

            console.log("异步任务执行了", p);
        }, 2000);



    });
    console.log(p);  //  {<pending>:undefined}







</script>

</html>